package middlewareWeb;

import java.util.*;

/**
 *Classe che modellizza il Front End che fa da tramite tra i proxy dei vari worker e i RM
 * durante la procedura di replicazione
 * @author jhonny
 */
public class FrontEndQueue extends Observable {
    private Vector<InfoRM> codaFrontEnd;
     /**
    *Metodo costruttore
    */
    public FrontEndQueue()
    {
        codaFrontEnd = new Vector<InfoRM>();
    }
    /**
    *Metodo che restituisce la coda di informazioni
    *@return vettore di oggetti InfoRM
    */
    public Vector<InfoRM> getCoda()
    {
        return this.codaFrontEnd;
    }
    /**
    *Metodo che inserisce un oggetto InfoRM dentro la coda
    *@param info informazione da aggiungere
    *@return boolean di riuscita dell'operazione
    */
    public synchronized boolean inserisci(InfoRM info)
    {
        boolean result = false;
        if(info.getClocks().isEmpty()){
            result = this.codaFrontEnd.add(info);
            this.setChanged();
            this.notifyObservers();
        } else {
            Iterator itr = this.codaFrontEnd.iterator();
            int index = -1;
            while(itr.hasNext()){
                InfoRM item = (InfoRM)itr.next();

                if(confronta(item.getClocks(),info.getClocks())>0)
                    index = this.codaFrontEnd.indexOf(item);
            }
            if (index==-1)
                result = this.codaFrontEnd.add(info);
            else{
                this.codaFrontEnd.insertElementAt(info, index);
                result = true;
            }
        }
        return result;
    }
    /**
    *Metodo che confronta due Hashtable
    *@param source oggetto HashTable
     * @param target    oggetto HashTable
     * @return -1 se source minore del target, 0 source minore uguale target, 1 altrimenti
    */
    public int confronta(Hashtable source, Hashtable target){
        Enumeration e = source.keys();
        String key = new String();
        boolean minore_uguale = true;
        boolean minore = false;
        while(e.hasMoreElements() && minore_uguale ){
            key = (String)e.nextElement();
            if((Integer)target.get(key)<(Integer)source.get(key)) minore_uguale = false;
            if((Integer)target.get(key)>(Integer)source.get(key)) minore = true;
        }
        if (minore && minore_uguale) return -1; //source < target
        if (!minore && minore_uguale) return 0; //source <= target
        return 1; //altrimenti
    }

    /**
    *Metodo rimuove un oggetto InfoRM dalla coda
    *@param indice dell'elemento che vogliamo eliminare
    */
    public synchronized void rimuovi(int index)
    {
        if (this.codaFrontEnd.get(index)!=null)
            this.codaFrontEnd.removeElementAt(index);
    }
}
